package com.smart.translate.handler;

import com.smart.translate.annotation.SmartTranslateAnnotation;
import com.smart.translate.config.SmartTranslateConfig;
import jakarta.annotation.Resource;
import org.springframework.context.ApplicationContext;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @ClassName SmartTranslateResponseAdvice
 * @Description TODO
 * @Author YY
 * @create: 2025−08-20 17:21
 */
@RestControllerAdvice
public class SmartTranslateResponseAdvice implements ResponseBodyAdvice<Object> {

    @Resource
    private ApplicationContext applicationContext;

    @Resource
    private SmartTranslateConfig smartTranslateConfig;


    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        // 拦截所有返回 JSON 的接口
        return true;
    }

    @Override
    public Object beforeBodyWrite(
            Object body,
            MethodParameter returnType,
            MediaType selectedContentType,
            Class selectedConverterType,
            ServerHttpRequest request,
            ServerHttpResponse response) {

        if (body == null) {
            return null;
        }

        // 如果是集合
        if (body instanceof Collection<?>) {
            List<Object> result = new ArrayList<>();
            for (Object obj : (Collection<?>) body) {
                result.add(processObject(obj));
            }
            return result;
        }

        // 如果是数组
        if (body.getClass().isArray()) {
            Object[] array = (Object[]) body;
            Object[] newArray = new Object[array.length];
            for (int i = 0; i < array.length; i++) {
                newArray[i] = processObject(array[i]);
            }
            return newArray;
        }

        // 普通对象
        return processObject(body);
    }

    private Object processObject(Object target) {
        if (target == null) {
            return null;
        }

        Class<?> clazz = target.getClass();

        // 如果关闭动态翻译 → 转换成 Map
        if (!smartTranslateConfig.getIsCustomize()) {
            return convertToMapWithTranslatedFields(target, clazz);
        }

        // 如果开启动态翻译 → 原地替换字段
        for (Field field : clazz.getDeclaredFields()) {
            SmartTranslateAnnotation annotation = field.getAnnotation(SmartTranslateAnnotation.class);
            if (annotation == null) {
                continue;
            }

            field.setAccessible(true);
            try {
                Object rawValue = field.get(target);
                SmartTranslateHandler handler = getHandler(annotation.handler());
                Object translated = handler.translate(rawValue, annotation, target);

                // 直接覆盖原字段值
                field.set(target, translated);

            } catch (Exception e) {
                throw new RuntimeException("SmartTranslate 翻译失败: " + field.getName(), e);
            }
        }

        return target;
    }

    private Map<String, Object> convertToMapWithTranslatedFields(Object target, Class<?> clazz) {
        Map<String, Object> result = new LinkedHashMap<>();

        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            try {
                Object rawValue = field.get(target);

                SmartTranslateAnnotation annotation = field.getAnnotation(SmartTranslateAnnotation.class);

                if (annotation == null) {
                    result.put(field.getName(), rawValue);
                    continue;
                }

                // 获取翻译结果
                SmartTranslateHandler handler = getHandler(annotation.handler());
                Object translated = handler.translate(rawValue, annotation, target);

                // 原字段
                result.put(field.getName(), rawValue);

                // 动态新增一个 xxxTranslated 字段
                result.put(field.getName() + "SmartTranslate", translated);

            } catch (Exception e) {
                throw new RuntimeException("SmartTranslate 动态新增字段失败: " + field.getName(), e);
            }
        }

        return result;
    }


    private SmartTranslateHandler getHandler(Class<? extends SmartTranslateHandler> handlerClass)
            throws Exception {
        try {
            return applicationContext.getBean(handlerClass);
        } catch (Exception e) {
            return handlerClass.getDeclaredConstructor().newInstance();
        }
    }
}

